﻿using System;
using System.Reactive.Linq;
using DeepEarth.Toolkit.Common;

namespace DeepEarth.Toolkit.Controls
{
	internal sealed class DrawingProcessorObservable : IObservable<Geometry.Data.Geometry>
	{
		private readonly DrawingProcessorBase processor;
		public DrawingProcessorObservable(DrawingProcessorBase processor)
		{
			if (processor == null) throw new ArgumentNullException("processor");

			this.processor = processor;
		}

		public IDisposable Subscribe(IObserver<Geometry.Data.Geometry> observer)
		{
			processor.Initialize();

			var evt = Observable.FromEventPattern((EventHandler<GeometryEventArgs> ev) => ev,
			                     ev => processor.GeometryProduced += ev,
			                     ev => processor.GeometryProduced -= ev);

			evt.Subscribe(x => observer.OnNext(x.EventArgs.Geometry));

			return processor;
		}
	}

	public enum DrawingType
	{
		Pushpin,
		FreeDrawing
	}

	public static class DrawingObservable
	{
		public static IObservable<Geometry.Data.Geometry> Create(MapInteractionControl control, DrawingType type)
		{
			if (control == null) throw new ArgumentNullException("control");

			switch (type)
			{
				case DrawingType.Pushpin:
					return new DrawingProcessorObservable(new PushpinDrawProcessor(control));
				case DrawingType.FreeDrawing:
					return new DrawingProcessorObservable(new FreeDrawProcessor(control));
				default:
					throw new ArgumentOutOfRangeException("type");
			}
		}

		public static IObservable<Geometry.Data.Geometry> CreateShape(MapInteractionControl control)
		{
			return new DrawingProcessorObservable(new FreeDrawProcessor(control));
		}

		public static IObservable<Geometry.Data.Geometry> CreateShape(MapInteractionControl control, int maximumPoints)
		{
			return new DrawingProcessorObservable(new FreeDrawProcessor(control, maximumPoints));
		}

		public static IObservable<Geometry.Data.Geometry> CreateShape(MapInteractionControl control, int maximumPoints, bool closePoligon)
		{
			return new DrawingProcessorObservable(new FreeDrawProcessor(control, maximumPoints, closePoligon));
		}
	}
}